home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / file / managers / mc-3.2 / mc-3 / mc-3.2.1 / src / chown.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-17  |  7.9 KB  |  329 lines

  1. /* Chown command -- for the Midnight Commander
  2.    Copyright (C) 1994 Radek Doulik
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2 of the License, or
  7.    (at your option) any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
  17.  */
  18.  
  19. #include <config.h>
  20. #include <string.h>
  21. #include <stdio.h>
  22. #include <stdlib.h>    /* For malloc() */
  23.  
  24. #include <sys/types.h>
  25. #include <sys/param.h>
  26. #include <sys/stat.h>
  27. #include <grp.h>
  28. #include <pwd.h>
  29. #ifdef HAVE_UNISTD_H
  30. #   include <unistd.h>
  31. #endif
  32.  
  33. #include "tty.h"
  34. #include "mad.h"
  35. #include "util.h"        /* Needed for the externs */
  36. #include "win.h"
  37. #include "color.h"
  38. #include "dlg.h"
  39. #include "widget.h"
  40. #include "dialog.h"    /* For do_refresh() */
  41.  
  42. /* Needed for the extern declarations of integer parameters */
  43. #include "dir.h"
  44. #include "panel.h"        /* Needed for the externs */
  45. #include "file.h"
  46. #include "chmod.h"
  47. #include "main.h"
  48. #include "chown.h"
  49. #include "wtools.h"        /* For init_box_colors */
  50.  
  51. #define UX        5
  52. #define UY        2
  53.  
  54. #define GX              27
  55. #define GY              2
  56.  
  57. #define BX        5
  58. #define BY        15
  59.  
  60. #define TX              50
  61. #define TY              2
  62.  
  63. #define BUTTONS        5
  64.  
  65. #define B_SETALL        B_USER
  66. #define B_SETUSR        B_USER + 1
  67. #define B_SETGRP        B_USER + 2
  68.  
  69. /* struct stat *sf_stat; */
  70. static int need_update, end_chown;
  71. static int current_file;
  72. static int single_set;
  73. static WListbox *l_user, *l_group;
  74.  
  75. static struct {
  76.     int ret_cmd, y, x;
  77.     char *text;
  78.     int hkey, hpos;
  79. } chown_but[BUTTONS] = {
  80.      { B_CANCEL, 0, 54, "[ Cancel ]", 'c', 2, },
  81.      { B_ENTER, 0, 45, "[ Set ]", 's', 2, },
  82.      { B_SETUSR, 0, 29, "[ Set users ]", 'u', 6, },
  83.      { B_SETGRP, 0, 13, "[ Set groups ]", 'g', 6, },
  84.      { B_SETALL, 0, 0, "[ Set all ]", 'a', 6, },
  85. };
  86.  
  87. #define LABELS 5 
  88. static struct {
  89.     int y, x;
  90.     WLabel *l;
  91. } chown_label [LABELS] = {
  92. { TY+2, TX+2 },
  93. { TY+4, TX+2 },
  94. { TY+6, TX+2 },
  95. { TY+8, TX+2 },
  96. { TY+10,TX+2 }
  97. };
  98.  
  99. #ifndef HAVE_X
  100. static void chown_refresh (void)
  101. {
  102.     attrset (REVERSE_COLOR);
  103.     dlg_erase (ch_dlg);
  104.  
  105.     draw_box (ch_dlg, 1, 2, 16, 70);
  106.     draw_box (ch_dlg, UY, UX, 12, 21);
  107.     draw_box (ch_dlg, GY, GX, 12, 21);
  108.     draw_box (ch_dlg, TY, TX, 12, 19);
  109.  
  110.     attrset (COLOR_NORMAL);
  111.     dlg_move (ch_dlg, TY + 1, TX + 1);
  112.     addstr (" Name ");
  113.     dlg_move (ch_dlg, TY + 3, TX + 1);
  114.     addstr (" Owner name ");
  115.     dlg_move (ch_dlg, TY + 5, TX + 1);
  116.     addstr (" Group name ");
  117.     dlg_move (ch_dlg, TY + 7, TX + 1);
  118.     addstr (" Size ");
  119.     dlg_move (ch_dlg, TY + 9, TX + 1);
  120.     addstr (" Permission ");
  121.     
  122.     attrset (COLOR_HOT_NORMAL);
  123.     dlg_move (ch_dlg, 1, 28);
  124.     addstr (" Chown command ");
  125.     dlg_move (ch_dlg, UY, UX + 1);
  126.     addstr (" User name ");
  127.     dlg_move (ch_dlg, GY, GX + 1);
  128.     addstr (" Group name ");
  129.     dlg_move (ch_dlg, TY, TX + 1);
  130.     addstr (" File ");
  131. }
  132. #endif
  133.  
  134. static char *next_file (void)
  135. {
  136.     while (!cpanel->dir.list[current_file].f.marked)
  137.     current_file++;
  138.  
  139.     return cpanel->dir.list[current_file].fname;
  140. }
  141.  
  142. static int chown_callback (Dlg_head * h, int Par, int Msg)
  143. {
  144.     switch (Msg) {
  145. #ifndef HAVE_X
  146.     case DLG_DRAW:
  147.       chown_refresh ();
  148.       break;
  149. #endif
  150.     }
  151.     return 0;
  152. }
  153.  
  154. static int l_call (void *data)
  155. {
  156.     return 1;
  157. }
  158.  
  159. static void init_chown (void)
  160. {
  161.     int i;
  162.     struct passwd *l_pass;
  163.     struct group *l_grp;
  164.  
  165.     do_refresh ();
  166.     end_chown = need_update = current_file = 0;
  167.     single_set = (cpanel->marked < 2) ? 3 : 0;    
  168.  
  169.     ch_dlg = create_dlg (0, 0, 18, 74, dialog_colors, chown_callback,
  170.              "[Chown]", "chown", DLG_CENTER);
  171.  
  172. #define XTRACT(i) BY+chown_but[i].y, BX+chown_but[i].x, chown_but[i].ret_cmd, chown_but[i].text, chown_but[i].hkey, chown_but[i].hpos, 0, 0
  173.  
  174.     tk_new_frame (ch_dlg, "b.");
  175.     for (i = 0; i < BUTTONS-single_set; i++)
  176.     add_widget (ch_dlg, button_new (XTRACT (i)));
  177.  
  178.     /* Add the widgets for the file information */
  179. #define LX(i) chown_label [i].y, chown_label [i].x, ""
  180.     tk_new_frame (ch_dlg, "l.");
  181.     for (i = 0; i < LABELS; i++){
  182.     chown_label [i].l = label_new (LX (i));
  183.     add_widget (ch_dlg, chown_label [i].l);
  184.     }
  185.  
  186.     /* get new listboxes */
  187.     l_user = listbox_new (UY + 1, UX + 1, 19, 10, 0, l_call);
  188.     l_group = listbox_new (GY + 1, GX + 1, 19, 10, 0, l_call);
  189.  
  190.     listbox_add_item (l_user, 0, 0, "<Unknown user>", NULL);    /* add fields for unknown names (numbers) */
  191.     listbox_add_item (l_group, 0, 0, "<Unknown group>", NULL);
  192.  
  193.     setpwent ();        /* get and put user names in the listbox */
  194.     while ((l_pass = getpwent ())) {
  195.     listbox_add_item (l_user, 0, 0, l_pass->pw_name, NULL);
  196.     }
  197.  
  198.     setgrent ();        /* get and put group names in the listbox */
  199.     while ((l_grp = getgrent ())) {
  200.     listbox_add_item (l_group, 0, 0, l_grp->gr_name, NULL);
  201.     }
  202.  
  203.     tk_new_frame (ch_dlg, "f.");
  204.     add_widget (ch_dlg, l_group);
  205.     tk_new_frame (ch_dlg, "g.");
  206.     add_widget (ch_dlg, l_user);    /* add listboxes to the dialogs */
  207.     tk_end_frame ();
  208. }
  209.  
  210. void chown_done (void)
  211. {
  212.     if (need_update)
  213.     update_panels (UP_OPTIMIZE, UP_KEEPSEL, UP_KEEPSEL);
  214.     repaint_screen ();
  215. }
  216.  
  217. static inline void do_chown (uid_t u, gid_t g)
  218. {
  219.     chown (cpanel->dir.list [current_file].fname, u, g);
  220.     file_mark (cpanel, current_file, 0);
  221. }
  222.  
  223. static void apply_chowns (uid_t u, gid_t g)
  224. {
  225.     char *fname;
  226.   
  227.     need_update = end_chown = 1;
  228.     do_chown (u,g);
  229.     cpanel->marked--;
  230.   
  231.     do {
  232.     fname = next_file ();
  233.     
  234.     do_chown (u,g);
  235.     cpanel->marked--;
  236.     } while (cpanel->marked);
  237. }
  238.  
  239. #define chown_label(n,txt) label_set_text (chown_label [n].l, txt)
  240.  
  241. void chown_cmd (void)
  242. {
  243.     char *fname;
  244.     struct stat sf_stat;
  245.     WLEntry *fe;
  246.     uid_t new_user;
  247.     gid_t new_group;
  248.     char  buffer [15];
  249.  
  250.     do {            /* do while any files remaining */
  251.     init_chown ();
  252.     new_user = new_group = -1;
  253.  
  254.     if (cpanel->marked)
  255.         fname = next_file ();            /* next marked file */
  256.     else
  257.         fname = selection (cpanel)->fname;            /* single file */
  258.     
  259.     if (!stat_file (fname, &sf_stat))    /* get status of file */
  260.         break;
  261.     
  262.     /* select in listboxes */
  263.     fe = listbox_search_text (l_user, get_owner(sf_stat.st_uid));
  264.     if (fe)
  265.         listbox_select_entry (l_user, fe);
  266.     
  267.     fe = listbox_search_text (l_group, get_group(sf_stat.st_gid));
  268.     if (fe)
  269.         listbox_select_entry (l_group, fe);
  270.  
  271.         chown_label (0, name_trunc (fname, 15));
  272.         chown_label (1, name_trunc (get_owner (sf_stat.st_uid), 15));
  273.     chown_label (2, name_trunc (get_group (sf_stat.st_gid), 15));
  274.         sprintf (buffer, "%d", c_fsize);
  275.     chown_label (3, buffer);
  276.     chown_label (4, string_perm (sf_stat.st_mode));
  277.  
  278.     run_dlg (ch_dlg);
  279.     
  280.     switch (ch_dlg->ret_value) {
  281.     case B_CANCEL:
  282.         end_chown = 1;
  283.         break;
  284.         
  285.     case B_SETUSR:
  286.     {
  287.         struct passwd *user;
  288.  
  289.         user = getpwnam (l_user->current->text);
  290.         if (user){
  291.         new_user = user->pw_uid;
  292.         apply_chowns (new_user, new_group);
  293.         }
  294.         break;
  295.     }   
  296.     case B_SETGRP:
  297.     {
  298.         struct group *grp;
  299.  
  300.         grp = getgrnam (l_group->current->text);
  301.         if (grp){
  302.         new_group = grp->gr_gid;
  303.         apply_chowns (new_user, new_group);
  304.         }
  305.         break;
  306.     }
  307.     case B_SETALL:
  308.     case B_ENTER:
  309.         new_group = (getgrnam (l_group->current->text))->gr_gid;
  310.         new_user = (getpwnam (l_user->current->text))->pw_uid;
  311.         if (ch_dlg->ret_value==B_ENTER) {
  312.         need_update = 1;
  313.         chown (fname, new_user, new_group);
  314.         } else
  315.         apply_chowns (new_user, new_group);
  316.         break;
  317.     }
  318.     
  319.     if (cpanel->marked && ch_dlg->ret_value != B_CANCEL){
  320.         file_mark (cpanel, current_file, 0);
  321.         cpanel->marked--;
  322.         need_update = 1;
  323.     }
  324.     destroy_dlg (ch_dlg);
  325.     } while (cpanel->marked && !end_chown);
  326.     
  327.     chown_done ();
  328. }
  329.